package com.atguigu.gulimall.gulimallsearch.thread;

import java.util.concurrent.*;

/**
 * <p>Title: ThreadTest</p>
 * Description：
 * date：2020/6/23 20:35
 */
public class ThreadTest {

	public static ExecutorService service = Executors.newFixedThreadPool(10);//线程池
	/**
	 * 1. corePoolSize: 池中一直保持的线程的数量，即使线程空闲。除非设置了 allowCoreThreadTimeOut
	 * 2. maximumPoolSize: 池中允许的最大的线程数
	 * 3. keepAliveTime: 当线程数大于核心线程数的时候，超出核心线程数的线程在最大多长时间没有接到新任务就会终止释放 ，最终线程池维持在 corePoolSize 大小
	 * 4. unit: 时间单位
	 * 5. workQueue: 阻塞队列，用来存储等待执行的任务，如果当前对线程的需求超过了 corePoolSize大小， 就 会放在这里 等待空闲线程执行.
	 * 6. threadFactory：创建线程的工厂，比如指定线程名等
	 * 7. handler：拒绝策略，如果线程满了，线程池就会使用拒绝策略。
	 * -----------------------------------------------------------------------------------------------------------
	 * 1、线程池创建，准备好 core 数量的核心线程，准备接受任务
	 * 2、新的任务进来，用 core 准备好的空闲线程执行。
	 * (1) 、core 满了，就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队列获取任务执行
	 * (2) 、阻塞队列满了，就直接开新线程执行，最大只能开到 max 指定的数量
	 * (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自动销毁。最终保持到core 大小
	 * (4) 、如果线程数开到了 max 的数量，还有新任务进来，就会使用 reject 指定的拒绝策略进行处理
	 * 3、所有的线程创建都是由指定的 factory 创建的
	 * 一个线程池 core 7； ； max 20  ，queue ：50 ，100 并发进来怎么分配的；
	 * 先有 7 个能直接得到执行，接下来 50 个进入队列排队，在多开 13 个继续执行。现在 70 个
	 * 被安排上了。剩下 30 个使用拒绝策略。
	 */

	public static void main(String[] args) throws Exception {
		System.out.println("start");

        /**
         * 方法完成后的感知
         */
//		CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {//没有返回值
//			System.out.println("当前线程" + Thread.currentThread().getId());
//			int i = 10 / 2;
//			System.out.println("运行结果" + i);
//		}, service);
//		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {//有返回值
//			System.out.println("当前线程" + Thread.currentThread().getId());
//			int i = 10 / 0;
//			System.out.println("运行结果" + i);
//			return i;
//		}, service).whenComplete((res,exception)->{//正常完成,感知异常,返回
//			System.out.println("10/5结果是"+res+"异常是"+exception);
//		}).exceptionally(throwable -> {//感知异常,返回默认值
//			return 10;
//		});

        /**
         * 方法执行完成后的处理
         */
//		CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {//有返回值
//			System.out.println("当前线程" + Thread.currentThread().getId());
//			int i = 10 / 0;
//			System.out.println("运行结果" + i);
//			return i;
//		}, service).handle((res,exception)->{
//			if(res != null){
//				return res*2;
//			}
//			if(exception != null){
//				return 0;
//			}
//			return 0;
//		});
        /**
         * 程序串行话
         * thenRun:不能获取到上一步的结果,不支持返回值
         * .thenRunAsync(() -> {
         *             System.out.println("任务2启动了");
         *
         *      .thenRunAsync(() -> {
         *             System.out.println("任务2启动了");
         *      thenRunAsync;能接收上一步结果.但无返回值
         *
         */

//        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {//有返回值
//            System.out.println("当前线程" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("运行结果" + i);
//            return i;
//        }, service).thenApplyAsync(res -> {
//            System.out.println(res);
//            return res * 2 + "hello,world";
//        }, service);
//
//        String s = future.get();
//
//        System.out.println(s);
//        System.out.println("main....end");

        /**
         * 两任务合并
         */

        CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println("任务1线程结束" + i);
            return i;
        }, service);


        CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程" + Thread.currentThread().getId());
			System.out.println("任务2线程结束");

            return "hello,world";

        }, service);
//        future1.runAfterBothAsync(future2,()->{
//            System.out.println("任务3线程"+Thread.currentThread().getId());
//        },service);
        // 合并上面两个任务 可以感知前面任务的结果
//        future1.thenAcceptBothAsync(future2,(res1, res2) -> {
//			System.out.println("任务3开始... 任务1的结果：" + res1 + "任务2的结果：" + res2);
//		},service);

//        CompletableFuture<String> future = future1.thenCombineAsync(future2, (res1, res2) -> {
//            return res1 + "------------------>" + res2;
//        }, service);
//        String s = future.get();
//        System.out.println(s);

		/**
		 * 合并两个任务 其中任何一个完成了 就执行这个
		 * 不感知结果,自己也无返回值
		 */
//		future1.runAfterEitherAsync(future2,()->{
//			System.out.println("任务3线程开始,,,,,,之前的结果:");
//		},service);
		/**
         * 合并两个任务 其中任何一个完成了 就执行这个
         * 感知结果,自己有返回值
         */

//		future1.acceptEitherAsync(future2,(res)->{
//			System.out.println("任务3线程开始,,,,,,之前的结果:"+res);
//		},service);
//		CompletableFuture<String> future = future1.applyToEitherAsync(future2, res -> {
//			System.out.println("任务3线程开始,,,,,,之前的结果:" + res);
//			return res.toString() + "哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇";
//		}, service);
//		String s = future.get();
//		System.out.println(s);
		CompletableFuture<String> futureimg = future1.supplyAsync(() -> {
			System.out.println("查询图片信息");
			return "hello.jpg";
		}, service);
		CompletableFuture<String> futureAttr = future1.supplyAsync(() -> {
			System.out.println("查询图片属性");
			return "黑色256g";
		}, service);
		CompletableFuture<String> futureDesc = future1.supplyAsync(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("查询图片介绍");
			return "华为";
		}, service);
		// 三个任务都完成
//		CompletableFuture<Void> completableFuture = CompletableFuture.allOf(futureimg, futureAttr, futureDesc);
		// 三个任务只要有一个完成 就执行
		CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(futureimg, futureAttr, futureDesc);
		objectCompletableFuture.get();

		System.out.println("main....end");
    }





	public  void thread (String[] args) throws ExecutionException, InterruptedException {
//		System.out.println("main....start");
//		ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
//				200,
//				10,
//				TimeUnit.SECONDS,
//				new LinkedBlockingDeque<>(100000),
//				Executors.defaultThreadFactory(),
//				new ThreadPoolExecutor.AbortPolicy());
//		System.out.printf("11111-------------"+ Integer.MAX_VALUE);





	}

}
